<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 10 Working with Shiny | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.20 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 10 Working with Shiny | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 10 Working with Shiny | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-08-20" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="crosstalk.html"/>
<link rel="next" href="discover.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/accessible-code-block/empty-anchor.js"></script>
<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>
<script src="libs/viz/viz.js"></script>
<link href="libs/DiagrammeR-styles/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding/grViz.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#disclaimer"><i class="fa fa-check"></i>Disclaimer</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a>
<ul>
<li class="chapter" data-level="1.1" data-path="introduction.html"><a href="introduction.html#rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="introduction.html"><a href="introduction.html#methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a>
<ul>
<li class="chapter" data-level="1.2.1" data-path="introduction.html"><a href="introduction.html#v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
<li class="chapter" data-level="1.2.4" data-path="introduction.html"><a href="introduction.html#bubble"><i class="fa fa-check"></i><b>1.2.4</b> bubble</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="introduction.html"><a href="introduction.html#methods-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a>
<ul>
<li class="chapter" data-level="1.3.1" data-path="introduction.html"><a href="introduction.html#reactr"><i class="fa fa-check"></i><b>1.3.1</b> reactR</a></li>
<li class="chapter" data-level="1.3.2" data-path="introduction.html"><a href="introduction.html#r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a>
<ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#r-package-development"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a>
<ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#creating-a-package"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#build-load-and-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#json"><i class="fa fa-check"></i><b>2.2</b> JSON</a>
<ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#tabular-data"><i class="fa fa-check"></i><b>2.2.2</b> Tabular data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a>
<ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#developer-tools"><i class="fa fa-check"></i><b>2.3.1</b> Developer tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#variable-declaration-and-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable declaration and scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#document-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document object model</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html"><i class="fa fa-check"></i><b>3</b> Introduction to widgets</a>
<ul>
<li class="chapter" data-level="3.1" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#plotly-package"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#dt-package"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html"><i class="fa fa-check"></i><b>4</b> Basics of building widgets</a>
<ul>
<li class="chapter" data-level="4.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#candidate-libraries"><i class="fa fa-check"></i><b>4.1</b> Candidate Libraries</a>
<ul>
<li class="chapter" data-level="4.1.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#plotly"><i class="fa fa-check"></i><b>4.1.1</b> Plotly</a></li>
<li class="chapter" data-level="4.1.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#highchart.js"><i class="fa fa-check"></i><b>4.1.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.1.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#chart.js"><i class="fa fa-check"></i><b>4.1.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>4.2</b> How it works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="your-first-widget.html"><a href="your-first-widget.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a>
<ul>
<li class="chapter" data-level="5.1" data-path="your-first-widget.html"><a href="your-first-widget.html#the-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="your-first-widget.html"><a href="your-first-widget.html#the-output"><i class="fa fa-check"></i><b>5.2</b> The Output</a></li>
<li class="chapter" data-level="5.3" data-path="your-first-widget.html"><a href="your-first-widget.html#javascript-side"><i class="fa fa-check"></i><b>5.3</b> JavaScript-side</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a>
<ul>
<li class="chapter" data-level="6.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#dependency"><i class="fa fa-check"></i><b>6.1</b> Dependency</a></li>
<li class="chapter" data-level="6.2" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>6.2</b> JavaScript</a></li>
<li class="chapter" data-level="6.3" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#html-element"><i class="fa fa-check"></i><b>6.3</b> HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="the-full-monty.html"><a href="the-full-monty.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a>
<ul>
<li class="chapter" data-level="7.1" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>7.1</b> Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>7.2</b> JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="the-full-monty.html"><a href="the-full-monty.html#transforming-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a>
<ul>
<li class="chapter" data-level="7.4.1" data-path="the-full-monty.html"><a href="the-full-monty.html#in-javascript"><i class="fa fa-check"></i><b>7.4.1</b> In JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="the-full-monty.html"><a href="the-full-monty.html#in-r"><i class="fa fa-check"></i><b>7.4.2</b> In R</a></li>
<li class="chapter" data-level="7.4.3" data-path="the-full-monty.html"><a href="the-full-monty.html#pros-cons"><i class="fa fa-check"></i><b>7.4.3</b> Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="the-full-monty.html"><a href="the-full-monty.html#on-print"><i class="fa fa-check"></i><b>7.5</b> On Print</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="advanced-topics.html"><a href="advanced-topics.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a>
<ul>
<li class="chapter" data-level="8.1" data-path="advanced-topics.html"><a href="advanced-topics.html#shared-variables"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a>
<ul>
<li class="chapter" data-level="8.1.1" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="advanced-topics.html"><a href="advanced-topics.html#resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="advanced-topics.html"><a href="advanced-topics.html#pre-render-hooks-security"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks &amp; Security</a></li>
<li class="chapter" data-level="8.4" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="advanced-topics.html"><a href="advanced-topics.html#prepend-append-content"><i class="fa fa-check"></i><b>8.5</b> Prepend &amp; Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="advanced-topics.html"><a href="advanced-topics.html#compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="advanced-topics.html"><a href="advanced-topics.html#unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="crosstalk.html"><a href="crosstalk.html"><i class="fa fa-check"></i><b>9</b> Crosstalk</a>
<ul>
<li class="chapter" data-level="9.1" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-example"><i class="fa fa-check"></i><b>9.1</b> Crosstalk example</a></li>
<li class="chapter" data-level="9.2" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-requirements"><i class="fa fa-check"></i><b>9.2</b> Crosstalk requirements</a></li>
<li class="chapter" data-level="9.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>9.3</b> How it works</a></li>
<li class="chapter" data-level="9.4" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-with-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with gio</a></li>
<li class="chapter" data-level="9.5" data-path="crosstalk.html"><a href="crosstalk.html#use-it-in-shiny"><i class="fa fa-check"></i><b>9.5</b> Use it in Shiny</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="working-with-shiny.html"><a href="working-with-shiny.html"><i class="fa fa-check"></i><b>10</b> Working with Shiny</a>
<ul>
<li class="chapter" data-level="10.1" data-path="working-with-shiny.html"><a href="working-with-shiny.html#javascript-to-r"><i class="fa fa-check"></i><b>10.1</b> JavaScript to R</a></li>
<li class="chapter" data-level="10.2" data-path="working-with-shiny.html"><a href="working-with-shiny.html#input-handler"><i class="fa fa-check"></i><b>10.2</b> Input Handler</a></li>
<li class="chapter" data-level="10.3" data-path="working-with-shiny.html"><a href="working-with-shiny.html#r-to-javascript"><i class="fa fa-check"></i><b>10.3</b> R to JavaScript</a>
<ul>
<li class="chapter" data-level="10.3.1" data-path="working-with-shiny.html"><a href="working-with-shiny.html#send-data"><i class="fa fa-check"></i><b>10.3.1</b> Send Data</a></li>
<li class="chapter" data-level="10.3.2" data-path="working-with-shiny.html"><a href="working-with-shiny.html#retrieve-widget-instance"><i class="fa fa-check"></i><b>10.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="10.3.3" data-path="working-with-shiny.html"><a href="working-with-shiny.html#handle-data"><i class="fa fa-check"></i><b>10.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="10.4" data-path="working-with-shiny.html"><a href="working-with-shiny.html#proxy-function"><i class="fa fa-check"></i><b>10.4</b> Proxy Function</a></li>
<li class="chapter" data-level="10.5" data-path="working-with-shiny.html"><a href="working-with-shiny.html#clear-data"><i class="fa fa-check"></i><b>10.5</b> Clear Data</a></li>
<li class="chapter" data-level="10.6" data-path="working-with-shiny.html"><a href="working-with-shiny.html#update"><i class="fa fa-check"></i><b>10.6</b> Update</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="11" data-path="discover.html"><a href="discover.html"><i class="fa fa-check"></i><b>11</b> Discover</a>
<ul>
<li class="chapter" data-level="11.1" data-path="discover.html"><a href="discover.html#static-files"><i class="fa fa-check"></i><b>11.1</b> Static Files</a></li>
<li class="chapter" data-level="11.2" data-path="discover.html"><a href="discover.html#example---alerts"><i class="fa fa-check"></i><b>11.2</b> Example - Alerts</a></li>
<li class="chapter" data-level="11.3" data-path="discover.html"><a href="discover.html#from-r-to-javascript"><i class="fa fa-check"></i><b>11.3</b> From R to JavaScript</a></li>
<li class="chapter" data-level="11.4" data-path="discover.html"><a href="discover.html#from-javascript-to-r"><i class="fa fa-check"></i><b>11.4</b> From JavaScript to R</a></li>
<li class="chapter" data-level="11.5" data-path="discover.html"><a href="discover.html#deserialise"><i class="fa fa-check"></i><b>11.5</b> Deserialise</a></li>
</ul></li>
<li class="chapter" data-level="12" data-path="a-complete-integration.html"><a href="a-complete-integration.html"><i class="fa fa-check"></i><b>12</b> A Complete Integration</a>
<ul>
<li class="chapter" data-level="12.1" data-path="a-complete-integration.html"><a href="a-complete-integration.html#serialisation"><i class="fa fa-check"></i><b>12.1</b> Serialisation</a></li>
<li class="chapter" data-level="12.2" data-path="a-complete-integration.html"><a href="a-complete-integration.html#events-callbacks"><i class="fa fa-check"></i><b>12.2</b> Events &amp; Callbacks</a></li>
<li class="chapter" data-level="12.3" data-path="a-complete-integration.html"><a href="a-complete-integration.html#as-a-package"><i class="fa fa-check"></i><b>12.3</b> As a Package</a>
<ul>
<li class="chapter" data-level="12.3.1" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>12.3.1</b> Dependencies</a></li>
<li class="chapter" data-level="12.3.2" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>12.3.2</b> R Code</a></li>
<li class="chapter" data-level="12.3.3" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>12.3.3</b> JavaScript Code</a></li>
<li class="chapter" data-level="12.3.4" data-path="working-with-shiny.html"><a href="working-with-shiny.html#input-handler"><i class="fa fa-check"></i><b>12.3.4</b> Input Handler</a></li>
<li class="chapter" data-level="12.3.5" data-path="a-complete-integration.html"><a href="a-complete-integration.html#wrapping-up"><i class="fa fa-check"></i><b>12.3.5</b> Wrapping up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="13" data-path="tips-tricks.html"><a href="tips-tricks.html"><i class="fa fa-check"></i><b>13</b> Tips &amp; Tricks</a>
<ul>
<li class="chapter" data-level="13.1" data-path="tips-tricks.html"><a href="tips-tricks.html#shiny-events"><i class="fa fa-check"></i><b>13.1</b> Shiny Events</a></li>
<li class="chapter" data-level="13.2" data-path="tips-tricks.html"><a href="tips-tricks.html#table-buttons"><i class="fa fa-check"></i><b>13.2</b> Table Buttons</a></li>
<li class="chapter" data-level="13.3" data-path="tips-tricks.html"><a href="tips-tricks.html#jquery---toggle"><i class="fa fa-check"></i><b>13.3</b> jQuery - Toggle</a></li>
</ul></li>
<li class="chapter" data-level="14" data-path="custom-outputs.html"><a href="custom-outputs.html"><i class="fa fa-check"></i><b>14</b> Custom Outputs</a>
<ul>
<li class="chapter" data-level="14.1" data-path="custom-outputs.html"><a href="custom-outputs.html#inner-workings"><i class="fa fa-check"></i><b>14.1</b> Inner-workings</a></li>
<li class="chapter" data-level="14.2" data-path="custom-outputs.html"><a href="custom-outputs.html#discover-lena.js"><i class="fa fa-check"></i><b>14.2</b> Discover Lena.js</a></li>
<li class="chapter" data-level="14.3" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>14.3</b> Setup</a></li>
<li class="chapter" data-level="14.4" data-path="custom-outputs.html"><a href="custom-outputs.html#output"><i class="fa fa-check"></i><b>14.4</b> Output</a></li>
<li class="chapter" data-level="14.5" data-path="custom-outputs.html"><a href="custom-outputs.html#render"><i class="fa fa-check"></i><b>14.5</b> Render</a></li>
<li class="chapter" data-level="14.6" data-path="custom-outputs.html"><a href="custom-outputs.html#javascript-binding"><i class="fa fa-check"></i><b>14.6</b> JavaScript Binding</a></li>
<li class="chapter" data-level="14.7" data-path="custom-outputs.html"><a href="custom-outputs.html#test"><i class="fa fa-check"></i><b>14.7</b> Test</a></li>
</ul></li>
<li class="part"><span><b>IV JavaScript for Computations</b></span></li>
<li class="chapter" data-level="15" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>15</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="15.1" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i><b>15.1</b> Installation</a></li>
<li class="chapter" data-level="15.2" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i><b>15.2</b> Basics</a></li>
<li class="chapter" data-level="15.3" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i><b>15.3</b> External Libraries</a></li>
<li class="chapter" data-level="15.4" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i><b>15.4</b> With Npm</a></li>
<li class="chapter" data-level="15.5" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i><b>15.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="node.html"><a href="node.html"><i class="fa fa-check"></i><b>16</b> Node.js with Bubble</a>
<ul>
<li class="chapter" data-level="16.1" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i><b>16.1</b> Basics</a></li>
<li class="chapter" data-level="16.2" data-path="node.html"><a href="node.html#r-markdown-engine"><i class="fa fa-check"></i><b>16.2</b> R Markdown Engine</a></li>
<li class="chapter" data-level="16.3" data-path="node.html"><a href="node.html#npm"><i class="fa fa-check"></i><b>16.3</b> Npm</a></li>
</ul></li>
<li class="part"><span><b>V Examples</b></span></li>
<li class="chapter" data-level="17" data-path="ploty.html"><a href="ploty.html"><i class="fa fa-check"></i><b>17</b> Ploty</a>
<ul>
<li class="chapter" data-level="17.1" data-path="discover.html"><a href="discover.html#discover"><i class="fa fa-check"></i><b>17.1</b> Discover</a></li>
<li class="chapter" data-level="17.2" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i><b>17.2</b> Basics</a></li>
<li class="chapter" data-level="17.3" data-path="working-with-shiny.html"><a href="working-with-shiny.html#javascript-to-r"><i class="fa fa-check"></i><b>17.3</b> JavaScript to R</a></li>
<li class="chapter" data-level="17.4" data-path="working-with-shiny.html"><a href="working-with-shiny.html#r-to-javascript"><i class="fa fa-check"></i><b>17.4</b> R to JavaScript</a></li>
<li class="chapter" data-level="17.5" data-path="ploty.html"><a href="ploty.html#size-resize"><i class="fa fa-check"></i><b>17.5</b> Size &amp; Resize</a></li>
<li class="chapter" data-level="17.6" data-path="ploty.html"><a href="ploty.html#performance-security"><i class="fa fa-check"></i><b>17.6</b> Performance &amp; Security</a></li>
</ul></li>
<li class="chapter" data-level="18" data-path="image-classifier.html"><a href="image-classifier.html"><i class="fa fa-check"></i><b>18</b> Image Classifier</a>
<ul>
<li class="chapter" data-level="18.1" data-path="discover.html"><a href="discover.html#discover"><i class="fa fa-check"></i><b>18.1</b> Discover</a></li>
<li class="chapter" data-level="18.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>18.2</b> Setup</a></li>
<li class="chapter" data-level="18.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>18.3</b> JavaScript</a></li>
<li class="chapter" data-level="18.4" data-path="working-with-shiny.html"><a href="working-with-shiny.html#input-handler"><i class="fa fa-check"></i><b>18.4</b> Input Handler</a></li>
</ul></li>
<li class="chapter" data-level="19" data-path="progress-bar.html"><a href="progress-bar.html"><i class="fa fa-check"></i><b>19</b> Progress Bar</a>
<ul>
<li class="chapter" data-level="19.1" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>19.1</b> R code</a></li>
<li class="chapter" data-level="19.2" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>19.2</b> JavaScript code</a></li>
<li class="chapter" data-level="19.3" data-path="progress-bar.html"><a href="progress-bar.html#events"><i class="fa fa-check"></i><b>19.3</b> Events</a></li>
</ul></li>
<li class="chapter" data-level="20" data-path="machine-learning.html"><a href="machine-learning.html"><i class="fa fa-check"></i><b>20</b> Machine Learning</a>
<ul>
<li class="chapter" data-level="20.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#dependency"><i class="fa fa-check"></i><b>20.1</b> Dependency</a></li>
<li class="chapter" data-level="20.2" data-path="machine-learning.html"><a href="machine-learning.html#simple-regression"><i class="fa fa-check"></i><b>20.2</b> Simple Regression</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="cookies.html"><a href="cookies.html"><i class="fa fa-check"></i><b>21</b> Cookies</a>
<ul>
<li class="chapter" data-level="21.1" data-path="cookies.html"><a href="cookies.html#discover-js-cookie"><i class="fa fa-check"></i><b>21.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="21.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>21.2</b> Setup</a></li>
<li class="chapter" data-level="21.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>21.3</b> JavaScript</a></li>
<li class="chapter" data-level="21.4" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>21.4</b> R Code</a></li>
</ul></li>
<li class="part"><span><b>VI Closing Remarks</b></span></li>
<li class="chapter" data-level="22" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>22</b> Conclusion</a>
<ul>
<li class="chapter" data-level="22.1" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>22.1</b> Performances</a></li>
<li class="chapter" data-level="22.2" data-path="conclusion.html"><a href="conclusion.html#road-ahead"><i class="fa fa-check"></i><b>22.2</b> Road ahead</a>
<ul>
<li class="chapter" data-level="22.2.1" data-path="conclusion.html"><a href="conclusion.html#computation"><i class="fa fa-check"></i><b>22.2.1</b> Computation</a></li>
<li class="chapter" data-level="22.2.2" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i><b>22.2.2</b> Shiny</a></li>
<li class="chapter" data-level="22.2.3" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i><b>22.2.3</b> htmlwidgets</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="working-with-shiny" class="section level1" number="10">
<h1><span class="header-section-number">Chapter 10</span> Working with Shiny</h1>
<p>A previous set of chapters explored how to make JavaScript and R communicate in shiny applications by passing data from the server to the client and back. This chapter explores how to apply that to htmlwidgets so they can provide additional functionalities when used in Shiny applications.</p>
<p>To demonstrate how to integrate these functionalities in widgets we shall implement them in the previously built gio package.</p>
<div id="javascript-to-r" class="section level2" number="10.1">
<h2><span class="header-section-number">10.1</span> JavaScript to R</h2>
<p>JavaScript visualisation libraries will often include callbacks or events that are triggered when the user interacts with the visualisation so one can have arbitrary code run when, for example, a user clicks a point on a scatter plot, or when the user clicks the legend of a chart. Gio.js provides a callback that is fired when a country is selected on the globe, this callback function accepts two objects, one containing data on the country selected and another containing data on the related countries (the arcs coming and leaving the selected country). These could send back to the R server where they could be used for many things like fetching more data on the selected country from a database, or use that information to generate a shiny UI element like displaying the flag of the selected country, and much, much more.</p>
<p>The <a href="https://giojs.org/html/docs/callbackPicked.html">documentation of gio.js</a> gives the following example callback function.</p>
<div class="sourceCode" id="cb173"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb173-1"><a href="working-with-shiny.html#cb173-1"></a><span class="co">// define callback function</span></span>
<span id="cb173-2"><a href="working-with-shiny.html#cb173-2"></a><span class="kw">function</span> <span class="at">callback</span> (selectedCountry<span class="op">,</span> relatedCountries) <span class="op">{</span></span>
<span id="cb173-3"><a href="working-with-shiny.html#cb173-3"></a>  <span class="va">console</span>.<span class="at">log</span>(selectedCountry)<span class="op">;</span></span>
<span id="cb173-4"><a href="working-with-shiny.html#cb173-4"></a>  <span class="va">console</span>.<span class="at">log</span>(relatedCountries)<span class="op">;</span></span>
<span id="cb173-5"><a href="working-with-shiny.html#cb173-5"></a><span class="op">}</span></span>
<span id="cb173-6"><a href="working-with-shiny.html#cb173-6"></a></span>
<span id="cb173-7"><a href="working-with-shiny.html#cb173-7"></a><span class="co">// use callback function</span></span>
<span id="cb173-8"><a href="working-with-shiny.html#cb173-8"></a><span class="va">controller</span>.<span class="at">onCountryPicked</span>(callback)<span class="op">;</span></span></code></pre></div>
<p>This defines a function named <code>callback</code> which takes the two aforementioned objects and logs them in the JavaScript console. Then the function is passed to the <code>controller</code> which will run it every time a country is picked (selected). This can be incorporated into the widget where instead of logging the data in the console it could be used to define two different shiny inputs.</p>
<div class="sourceCode" id="cb174"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb174-1"><a href="working-with-shiny.html#cb174-1"></a><span class="co">// gio.js</span></span>
<span id="cb174-2"><a href="working-with-shiny.html#cb174-2"></a><span class="co">// define callback function</span></span>
<span id="cb174-3"><a href="working-with-shiny.html#cb174-3"></a><span class="kw">function</span> <span class="at">callback</span> (selectedCountry<span class="op">,</span> relatedCountries) <span class="op">{</span></span>
<span id="cb174-4"><a href="working-with-shiny.html#cb174-4"></a>  <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="st">&#39;selected&#39;</span><span class="op">,</span> selectedCountry)<span class="op">;</span></span>
<span id="cb174-5"><a href="working-with-shiny.html#cb174-5"></a>  <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="st">&#39;related&#39;</span><span class="op">,</span> relatedCountries)<span class="op">;</span></span>
<span id="cb174-6"><a href="working-with-shiny.html#cb174-6"></a><span class="op">}</span></span></code></pre></div>
<p>However, this will generate an issue experienced in a previous chapter; multiple gio visualisations in a single shiny application would be defining the values of a single input. This can be remedied to by using the id of the visualisation to dynamically generate the input name.</p>
<div class="sourceCode" id="cb175"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb175-1"><a href="working-with-shiny.html#cb175-1"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb175-2"><a href="working-with-shiny.html#cb175-2"></a></span>
<span id="cb175-3"><a href="working-with-shiny.html#cb175-3"></a>  <span class="kw">var</span> controller <span class="op">=</span> <span class="kw">new</span> <span class="va">GIO</span>.<span class="at">Controller</span>(el)<span class="op">;</span></span>
<span id="cb175-4"><a href="working-with-shiny.html#cb175-4"></a>  <span class="va">controller</span>.<span class="at">addData</span>(<span class="va">x</span>.<span class="at">data</span>)<span class="op">;</span></span>
<span id="cb175-5"><a href="working-with-shiny.html#cb175-5"></a>  <span class="va">controller</span>.<span class="at">setStyle</span>(<span class="va">x</span>.<span class="at">style</span>)<span class="op">;</span></span>
<span id="cb175-6"><a href="working-with-shiny.html#cb175-6"></a></span>
<span id="cb175-7"><a href="working-with-shiny.html#cb175-7"></a>  <span class="co">// callback</span></span>
<span id="cb175-8"><a href="working-with-shiny.html#cb175-8"></a>  <span class="kw">function</span> <span class="at">callback</span> (selectedCountry<span class="op">,</span> relatedCountries) <span class="op">{</span></span>
<span id="cb175-9"><a href="working-with-shiny.html#cb175-9"></a>    <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="va">el</span>.<span class="at">id</span> <span class="op">+</span> <span class="st">&#39;_selected&#39;</span><span class="op">,</span> selectedCountry)<span class="op">;</span></span>
<span id="cb175-10"><a href="working-with-shiny.html#cb175-10"></a>    <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="va">el</span>.<span class="at">id</span> <span class="op">+</span> <span class="st">&#39;_related&#39;</span><span class="op">,</span> relatedCountries)<span class="op">;</span></span>
<span id="cb175-11"><a href="working-with-shiny.html#cb175-11"></a>  <span class="op">}</span></span>
<span id="cb175-12"><a href="working-with-shiny.html#cb175-12"></a></span>
<span id="cb175-13"><a href="working-with-shiny.html#cb175-13"></a>  <span class="va">controller</span>.<span class="at">onCountryPicked</span>(callback)<span class="op">;</span></span>
<span id="cb175-14"><a href="working-with-shiny.html#cb175-14"></a></span>
<span id="cb175-15"><a href="working-with-shiny.html#cb175-15"></a>  <span class="co">// render</span></span>
<span id="cb175-16"><a href="working-with-shiny.html#cb175-16"></a>  <span class="va">controller</span>.<span class="at">init</span>()<span class="op">;</span></span>
<span id="cb175-17"><a href="working-with-shiny.html#cb175-17"></a></span>
<span id="cb175-18"><a href="working-with-shiny.html#cb175-18"></a><span class="op">}</span></span></code></pre></div>
<p>The package can then be installed with <code>devtools::install</code> so we can test these inputs in a shiny application.</p>
<div class="sourceCode" id="cb176"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb176-1"><a href="working-with-shiny.html#cb176-1"></a><span class="kw">library</span>(gio)</span>
<span id="cb176-2"><a href="working-with-shiny.html#cb176-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb176-3"><a href="working-with-shiny.html#cb176-3"></a></span>
<span id="cb176-4"><a href="working-with-shiny.html#cb176-4"></a><span class="co"># large sample data</span></span>
<span id="cb176-5"><a href="working-with-shiny.html#cb176-5"></a>url &lt;-<span class="st"> </span><span class="kw">paste0</span>(</span>
<span id="cb176-6"><a href="working-with-shiny.html#cb176-6"></a>  <span class="st">&quot;https://raw.githubusercontent.com/JohnCoene/&quot;</span>,</span>
<span id="cb176-7"><a href="working-with-shiny.html#cb176-7"></a>  <span class="st">&quot;javascript-for-r/master/data/countries.json&quot;</span></span>
<span id="cb176-8"><a href="working-with-shiny.html#cb176-8"></a>)</span>
<span id="cb176-9"><a href="working-with-shiny.html#cb176-9"></a>arcs &lt;-<span class="st"> </span>jsonlite<span class="op">::</span><span class="kw">fromJSON</span>(url)</span>
<span id="cb176-10"><a href="working-with-shiny.html#cb176-10"></a></span>
<span id="cb176-11"><a href="working-with-shiny.html#cb176-11"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb176-12"><a href="working-with-shiny.html#cb176-12"></a>  <span class="kw">gioOutput</span>(<span class="st">&quot;globe&quot;</span>),</span>
<span id="cb176-13"><a href="working-with-shiny.html#cb176-13"></a>  <span class="kw">fluidRow</span>(</span>
<span id="cb176-14"><a href="working-with-shiny.html#cb176-14"></a>    <span class="kw">column</span>(<span class="dv">6</span>, <span class="kw">verbatimTextOutput</span>(<span class="st">&quot;selectedCountry&quot;</span>)),</span>
<span id="cb176-15"><a href="working-with-shiny.html#cb176-15"></a>    <span class="kw">column</span>(<span class="dv">6</span>, <span class="kw">verbatimTextOutput</span>(<span class="st">&quot;relatedCountries&quot;</span>))</span>
<span id="cb176-16"><a href="working-with-shiny.html#cb176-16"></a>  )</span>
<span id="cb176-17"><a href="working-with-shiny.html#cb176-17"></a>)</span>
<span id="cb176-18"><a href="working-with-shiny.html#cb176-18"></a></span>
<span id="cb176-19"><a href="working-with-shiny.html#cb176-19"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb176-20"><a href="working-with-shiny.html#cb176-20"></a></span>
<span id="cb176-21"><a href="working-with-shiny.html#cb176-21"></a>  output<span class="op">$</span>globe &lt;-<span class="st"> </span><span class="kw">renderGio</span>({</span>
<span id="cb176-22"><a href="working-with-shiny.html#cb176-22"></a>    <span class="kw">gio</span>(arcs)</span>
<span id="cb176-23"><a href="working-with-shiny.html#cb176-23"></a>  })</span>
<span id="cb176-24"><a href="working-with-shiny.html#cb176-24"></a></span>
<span id="cb176-25"><a href="working-with-shiny.html#cb176-25"></a>  output<span class="op">$</span>selectedCountry &lt;-<span class="st"> </span><span class="kw">renderPrint</span>({</span>
<span id="cb176-26"><a href="working-with-shiny.html#cb176-26"></a>    <span class="kw">print</span>(input<span class="op">$</span>globe_selected)</span>
<span id="cb176-27"><a href="working-with-shiny.html#cb176-27"></a>  })</span>
<span id="cb176-28"><a href="working-with-shiny.html#cb176-28"></a></span>
<span id="cb176-29"><a href="working-with-shiny.html#cb176-29"></a>  output<span class="op">$</span>relatedCountries &lt;-<span class="st"> </span><span class="kw">renderPrint</span>({</span>
<span id="cb176-30"><a href="working-with-shiny.html#cb176-30"></a>    <span class="kw">print</span>(input<span class="op">$</span>globe_related)</span>
<span id="cb176-31"><a href="working-with-shiny.html#cb176-31"></a>  })</span>
<span id="cb176-32"><a href="working-with-shiny.html#cb176-32"></a></span>
<span id="cb176-33"><a href="working-with-shiny.html#cb176-33"></a>}</span>
<span id="cb176-34"><a href="working-with-shiny.html#cb176-34"></a></span>
<span id="cb176-35"><a href="working-with-shiny.html#cb176-35"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/gio-shiny-input-no-handler.png" alt="" />
<p class="caption">Gio input data</p>
</div>
<p>One thing to note before moving on, the data is sent from the client to the server whether the inputs are used or not, though this likely will not negatively impact gio it can reduce performances if the callback function is triggered too frequently. For instance an input value set when the user hovers a scatter plot might lead to the event being fired very frequently and too much data being sent to the server, slowing things down and providing a poor experience.</p>
<p>Therefore one might consider making the capture of such event optional so the web browser is not strained unless explicitly asked by the developer of the application. This could be implemented with a simple function that sets a simple logical variable in the <code>x</code> object that is used in JavaScript to check whether to implement the callback function.</p>
<div class="sourceCode" id="cb177"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb177-1"><a href="working-with-shiny.html#cb177-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb177-2"><a href="working-with-shiny.html#cb177-2"></a>gio_capture_events &lt;-<span class="st"> </span><span class="cf">function</span>(g) {</span>
<span id="cb177-3"><a href="working-with-shiny.html#cb177-3"></a>  g<span class="op">$</span>x<span class="op">$</span>capture_events &lt;-<span class="st"> </span><span class="ot">TRUE</span></span>
<span id="cb177-4"><a href="working-with-shiny.html#cb177-4"></a>  <span class="kw">return</span>(g)</span>
<span id="cb177-5"><a href="working-with-shiny.html#cb177-5"></a>}</span></code></pre></div>
<p>Then this could be used in JavaScript with an if statement.</p>
<div class="sourceCode" id="cb178"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb178-1"><a href="working-with-shiny.html#cb178-1"></a><span class="cf">if</span>(<span class="va">x</span>.<span class="at">capture_events</span>)</span>
<span id="cb178-2"><a href="working-with-shiny.html#cb178-2"></a>  <span class="va">controller</span>.<span class="at">onCountryPicked</span>(callback)<span class="op">;</span></span></code></pre></div>
<p>One might also consider not sending back all the data. For instance, gio returns the coordinates of the selected country where from arcs connect; this is might be considered unnecessary. The code below only sets the input to the ISO code of the country selected.</p>
<div class="sourceCode" id="cb179"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb179-1"><a href="working-with-shiny.html#cb179-1"></a><span class="kw">function</span> <span class="at">callback</span> (selectedCountry<span class="op">,</span> relatedCountries) <span class="op">{</span></span>
<span id="cb179-2"><a href="working-with-shiny.html#cb179-2"></a>  <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="va">el</span>.<span class="at">id</span> <span class="op">+</span> <span class="st">&#39;_selected&#39;</span><span class="op">,</span> <span class="va">selectedCountry</span>.<span class="at">ISOCode</span>)<span class="op">;</span></span>
<span id="cb179-3"><a href="working-with-shiny.html#cb179-3"></a><span class="op">}</span></span></code></pre></div>
</div>
<div id="input-handler" class="section level2" number="10.2">
<h2><span class="header-section-number">10.2</span> Input Handler</h2>
<p>While input handlers were explored previously we found limited use for them as these were set to simple boolean values for which a preprocessor made little sense. It can be useful in this case as the inputs return more substantial data. Namely the input returning data on the related countries, it is converted from JSON to a list but could be reshaped to a data frame of arcs (looking like <code>gio</code>’s input data).</p>
<p>Below we create a handler that is going to loop over the list (over each arc) and return a data frame.</p>
<div class="sourceCode" id="cb180"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb180-1"><a href="working-with-shiny.html#cb180-1"></a><span class="co"># handler.R</span></span>
<span id="cb180-2"><a href="working-with-shiny.html#cb180-2"></a>related_countries_handler &lt;-<span class="st"> </span><span class="cf">function</span>(x, session, inputname){</span>
<span id="cb180-3"><a href="working-with-shiny.html#cb180-3"></a>  purrr<span class="op">::</span><span class="kw">map_dfr</span>(x, as.data.frame)</span>
<span id="cb180-4"><a href="working-with-shiny.html#cb180-4"></a>}</span></code></pre></div>
<p>Then the handler must be registered with shiny, since handlers can only be registered once a good place to put it this is in the <code>.onLoad</code> function of the package.</p>
<div class="sourceCode" id="cb181"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb181-1"><a href="working-with-shiny.html#cb181-1"></a><span class="co"># zzz.R</span></span>
<span id="cb181-2"><a href="working-with-shiny.html#cb181-2"></a>related_countries_handler &lt;-<span class="st"> </span><span class="cf">function</span>(x, session, inputname){</span>
<span id="cb181-3"><a href="working-with-shiny.html#cb181-3"></a>  purrr<span class="op">::</span><span class="kw">map_dfr</span>(x, as.data.frame)</span>
<span id="cb181-4"><a href="working-with-shiny.html#cb181-4"></a>}</span>
<span id="cb181-5"><a href="working-with-shiny.html#cb181-5"></a></span>
<span id="cb181-6"><a href="working-with-shiny.html#cb181-6"></a>.onLoad &lt;-<span class="st"> </span><span class="cf">function</span>(libname, pkgname) {</span>
<span id="cb181-7"><a href="working-with-shiny.html#cb181-7"></a>  shiny<span class="op">::</span><span class="kw">registerInputHandler</span>(<span class="st">&quot;gio.related.countries&quot;</span>, related_countries_handler)</span>
<span id="cb181-8"><a href="working-with-shiny.html#cb181-8"></a>}</span></code></pre></div>
<p>Finally, we can reinstall the package with <code>devtools::install</code> and create shiny application to observe the change. Below we use a large example dataset and, since the input now returns a data frame, we can display the input value in a table.</p>
<div class="sourceCode" id="cb182"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb182-1"><a href="working-with-shiny.html#cb182-1"></a><span class="kw">library</span>(DT)</span>
<span id="cb182-2"><a href="working-with-shiny.html#cb182-2"></a><span class="kw">library</span>(gio)</span>
<span id="cb182-3"><a href="working-with-shiny.html#cb182-3"></a><span class="kw">library</span>(shiny)</span>
<span id="cb182-4"><a href="working-with-shiny.html#cb182-4"></a></span>
<span id="cb182-5"><a href="working-with-shiny.html#cb182-5"></a><span class="co"># large sample data</span></span>
<span id="cb182-6"><a href="working-with-shiny.html#cb182-6"></a>url &lt;-<span class="st"> </span><span class="kw">paste0</span>(</span>
<span id="cb182-7"><a href="working-with-shiny.html#cb182-7"></a>  <span class="st">&quot;https://raw.githubusercontent.com/JohnCoene/&quot;</span>,</span>
<span id="cb182-8"><a href="working-with-shiny.html#cb182-8"></a>  <span class="st">&quot;javascript-for-r/master/data/countries.json&quot;</span></span>
<span id="cb182-9"><a href="working-with-shiny.html#cb182-9"></a>)</span>
<span id="cb182-10"><a href="working-with-shiny.html#cb182-10"></a>arcs &lt;-<span class="st"> </span>jsonlite<span class="op">::</span><span class="kw">fromJSON</span>(url)</span>
<span id="cb182-11"><a href="working-with-shiny.html#cb182-11"></a></span>
<span id="cb182-12"><a href="working-with-shiny.html#cb182-12"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb182-13"><a href="working-with-shiny.html#cb182-13"></a>  <span class="kw">gioOutput</span>(<span class="st">&quot;globe&quot;</span>),</span>
<span id="cb182-14"><a href="working-with-shiny.html#cb182-14"></a>  <span class="kw">DTOutput</span>(<span class="st">&quot;relatedCountries&quot;</span>)</span>
<span id="cb182-15"><a href="working-with-shiny.html#cb182-15"></a>)</span>
<span id="cb182-16"><a href="working-with-shiny.html#cb182-16"></a></span>
<span id="cb182-17"><a href="working-with-shiny.html#cb182-17"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb182-18"><a href="working-with-shiny.html#cb182-18"></a></span>
<span id="cb182-19"><a href="working-with-shiny.html#cb182-19"></a>  output<span class="op">$</span>globe &lt;-<span class="st"> </span><span class="kw">renderGio</span>({</span>
<span id="cb182-20"><a href="working-with-shiny.html#cb182-20"></a>    <span class="kw">gio</span>(arcs)</span>
<span id="cb182-21"><a href="working-with-shiny.html#cb182-21"></a>  })</span>
<span id="cb182-22"><a href="working-with-shiny.html#cb182-22"></a></span>
<span id="cb182-23"><a href="working-with-shiny.html#cb182-23"></a>  output<span class="op">$</span>relatedCountries &lt;-<span class="st"> </span><span class="kw">renderDT</span>({</span>
<span id="cb182-24"><a href="working-with-shiny.html#cb182-24"></a>    <span class="kw">datatable</span>(input<span class="op">$</span>globe_related)</span>
<span id="cb182-25"><a href="working-with-shiny.html#cb182-25"></a>  })</span>
<span id="cb182-26"><a href="working-with-shiny.html#cb182-26"></a></span>
<span id="cb182-27"><a href="working-with-shiny.html#cb182-27"></a>}</span>
<span id="cb182-28"><a href="working-with-shiny.html#cb182-28"></a></span>
<span id="cb182-29"><a href="working-with-shiny.html#cb182-29"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/gio-input-handler.png" alt="" />
<p class="caption">Gio input data transformed to a data frame</p>
</div>
</div>
<div id="r-to-javascript" class="section level2" number="10.3">
<h2><span class="header-section-number">10.3</span> R to JavaScript</h2>
<p>This book previously explored how to send data from the shiny server to the front-end, this section applies this to htmlwidgets. Currently, using gio in shiny consists of generating the globe with the <code>renderGio</code> and complimentary <code>gioOutput</code> functions. This generates the entire visualisation, it creates the HTML element where it places the globe, draws the arcs based on the data, sets the style, etc.</p>
<p>Now imagine that only one of those aspects needs changing, say the data, or the style, given the functions currently at hand one would have to redraw the entire visualisation, only this time changing the data or the style. This is inelegant and not efficient, most JavaScript visualisation libraries, including gio.js, will enable changing only certain aspects of the output without having to redraw it all from scratch.</p>
<p>Before we look into the implementation, let us create a shiny application which would benefit from such a feature. The shiny application below provides a drop-down menu to select between two datasets to draw on the globe, running it reveals an issue with gio though. Upon selecting a dataset with the drop down a second globe appears underneath the original one. This is because internally gio.js creates a new element (<code>&lt;canvas&gt;</code>) within the <code>&lt;div&gt;</code> created by <code>htmlwidgets</code> when running <code>init</code> regardless of whether one was already created. Therefore, every call to <code>init</code> creates a new <code>&lt;canvas&gt;</code> with a different globe. Note that most visualisation libraries <em>will not have that issue</em>, they will detect the existing output and override it instead.</p>
<div class="sourceCode" id="cb183"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb183-1"><a href="working-with-shiny.html#cb183-1"></a><span class="kw">library</span>(gio)</span>
<span id="cb183-2"><a href="working-with-shiny.html#cb183-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb183-3"><a href="working-with-shiny.html#cb183-3"></a></span>
<span id="cb183-4"><a href="working-with-shiny.html#cb183-4"></a>arcs1 &lt;-<span class="st"> </span><span class="kw">data.frame</span>(</span>
<span id="cb183-5"><a href="working-with-shiny.html#cb183-5"></a>  <span class="dt">e =</span> <span class="kw">c</span>(<span class="st">&quot;US&quot;</span>, <span class="st">&quot;CN&quot;</span>, <span class="st">&quot;RU&quot;</span>),</span>
<span id="cb183-6"><a href="working-with-shiny.html#cb183-6"></a>  <span class="dt">i =</span> <span class="kw">c</span>(<span class="st">&quot;CN&quot;</span>, <span class="st">&quot;RU&quot;</span>, <span class="st">&quot;US&quot;</span>),</span>
<span id="cb183-7"><a href="working-with-shiny.html#cb183-7"></a>  <span class="dt">v =</span> <span class="kw">c</span>(<span class="dv">100</span>, <span class="dv">120</span>, <span class="dv">130</span>)</span>
<span id="cb183-8"><a href="working-with-shiny.html#cb183-8"></a>)</span>
<span id="cb183-9"><a href="working-with-shiny.html#cb183-9"></a></span>
<span id="cb183-10"><a href="working-with-shiny.html#cb183-10"></a>arcs2 &lt;-<span class="st"> </span><span class="kw">data.frame</span>(</span>
<span id="cb183-11"><a href="working-with-shiny.html#cb183-11"></a>  <span class="dt">e =</span> <span class="kw">c</span>(<span class="st">&quot;CN&quot;</span>, <span class="st">&quot;CN&quot;</span>, <span class="st">&quot;JP&quot;</span>),</span>
<span id="cb183-12"><a href="working-with-shiny.html#cb183-12"></a>  <span class="dt">i =</span> <span class="kw">c</span>(<span class="st">&quot;IN&quot;</span>, <span class="st">&quot;JP&quot;</span>, <span class="st">&quot;US&quot;</span>),</span>
<span id="cb183-13"><a href="working-with-shiny.html#cb183-13"></a>  <span class="dt">v =</span> <span class="kw">c</span>(<span class="dv">100</span>, <span class="dv">120</span>, <span class="dv">130</span>)</span>
<span id="cb183-14"><a href="working-with-shiny.html#cb183-14"></a>)</span>
<span id="cb183-15"><a href="working-with-shiny.html#cb183-15"></a></span>
<span id="cb183-16"><a href="working-with-shiny.html#cb183-16"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb183-17"><a href="working-with-shiny.html#cb183-17"></a>  <span class="kw">selectInput</span>(</span>
<span id="cb183-18"><a href="working-with-shiny.html#cb183-18"></a>    <span class="st">&quot;dataset&quot;</span>, </span>
<span id="cb183-19"><a href="working-with-shiny.html#cb183-19"></a>    <span class="st">&quot;Select a dataset&quot;</span>, </span>
<span id="cb183-20"><a href="working-with-shiny.html#cb183-20"></a>    <span class="dt">choices =</span> <span class="kw">c</span>(<span class="st">&quot;First&quot;</span>, <span class="st">&quot;Second&quot;</span>)</span>
<span id="cb183-21"><a href="working-with-shiny.html#cb183-21"></a>  ),</span>
<span id="cb183-22"><a href="working-with-shiny.html#cb183-22"></a>  <span class="kw">gioOutput</span>(<span class="st">&quot;globe&quot;</span>)</span>
<span id="cb183-23"><a href="working-with-shiny.html#cb183-23"></a>)</span>
<span id="cb183-24"><a href="working-with-shiny.html#cb183-24"></a></span>
<span id="cb183-25"><a href="working-with-shiny.html#cb183-25"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb183-26"><a href="working-with-shiny.html#cb183-26"></a></span>
<span id="cb183-27"><a href="working-with-shiny.html#cb183-27"></a>  reactive_arcs &lt;-<span class="st"> </span><span class="kw">reactive</span>({</span>
<span id="cb183-28"><a href="working-with-shiny.html#cb183-28"></a>    <span class="cf">if</span>(input<span class="op">$</span>dataset <span class="op">==</span><span class="st"> &quot;First&quot;</span>) </span>
<span id="cb183-29"><a href="working-with-shiny.html#cb183-29"></a>      <span class="kw">return</span>(arcs1)</span>
<span id="cb183-30"><a href="working-with-shiny.html#cb183-30"></a>    <span class="kw">return</span>(arcs2)</span>
<span id="cb183-31"><a href="working-with-shiny.html#cb183-31"></a>  })</span>
<span id="cb183-32"><a href="working-with-shiny.html#cb183-32"></a></span>
<span id="cb183-33"><a href="working-with-shiny.html#cb183-33"></a>  output<span class="op">$</span>globe &lt;-<span class="st"> </span><span class="kw">renderGio</span>({</span>
<span id="cb183-34"><a href="working-with-shiny.html#cb183-34"></a>    <span class="kw">gio</span>(<span class="kw">reactive_arcs</span>())</span>
<span id="cb183-35"><a href="working-with-shiny.html#cb183-35"></a>  })</span>
<span id="cb183-36"><a href="working-with-shiny.html#cb183-36"></a></span>
<span id="cb183-37"><a href="working-with-shiny.html#cb183-37"></a>}</span>
<span id="cb183-38"><a href="working-with-shiny.html#cb183-38"></a></span>
<span id="cb183-39"><a href="working-with-shiny.html#cb183-39"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/gio-shiny-error.png" alt="" />
<p class="caption">Gio shiny error</p>
</div>
<p>A solution to this is to ensure the container (<code>el</code>) is empty before generating the visualisation. Incidentally this can be executed with a JavaScript method previously used in this book: <code>innerHTML</code>.</p>
<div class="sourceCode" id="cb184"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb184-1"><a href="working-with-shiny.html#cb184-1"></a><span class="co">// gio.js</span></span>
<span id="cb184-2"><a href="working-with-shiny.html#cb184-2"></a><span class="va">el</span>.<span class="at">innerHTML</span> <span class="op">=</span> <span class="st">&#39;&#39;</span><span class="op">;</span> <span class="co">// empty el</span></span>
<span id="cb184-3"><a href="working-with-shiny.html#cb184-3"></a>controller <span class="op">=</span> <span class="kw">new</span> <span class="va">GIO</span>.<span class="at">Controller</span>(el)<span class="op">;</span></span></code></pre></div>
<p>Now, using the dropdown to switch between dataset does not generate a new visualisation.</p>
<p>We got sidetracked but this had to be fixed. Ideally, when the user selects a dataset from the dropdown the entire visualisation is not redrawn, only the underlying data (the arcs) changes. To do so, a new set of functions divorced from the ones currently at hand needs to be created. This separation will allow leaving the already created functions as-is, using <code>gio</code> and its corresponding <code>renderValue</code> JavaScript function to initialise a visualisation, and have a separate family of functions dedicated to working with different JavaScript functions which circumvent <code>renderValue</code> and directly change aspects of the visualisation, such as the underlying dataset.</p>
<p>This involves a few moving parts, thankfully some of them were already explored, just not in the context of htmlwidgets. The scheme is to send data from R to JavaScript using the formerly exploited <code>session$sendCustomMessage</code>, then in JavaScript fetch the instance of the visualisation (<code>controller</code> in the case of gio) to interact with it (<code>e.g.: controller.addData(data);</code>).</p>
<div id="send-data" class="section level3" number="10.3.1">
<h3><span class="header-section-number">10.3.1</span> Send Data</h3>
<p>Let’s start by creating the R function used to send data to JavaScript. This is hopefully reminiscent of a previous chapter, this function sends a message to JavaScript where it is paired with “message handler” that does something with said message.</p>
<div class="sourceCode" id="cb185"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb185-1"><a href="working-with-shiny.html#cb185-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb185-2"><a href="working-with-shiny.html#cb185-2"></a>gio_send_data &lt;-<span class="st"> </span><span class="cf">function</span>(id, data, <span class="dt">session =</span> shiny<span class="op">::</span><span class="kw">getDefaultReactiveDomain</span>()){</span>
<span id="cb185-3"><a href="working-with-shiny.html#cb185-3"></a>  message &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">id =</span> id, <span class="dt">data =</span> data)</span>
<span id="cb185-4"><a href="working-with-shiny.html#cb185-4"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&quot;send-data&quot;</span>, message)</span>
<span id="cb185-5"><a href="working-with-shiny.html#cb185-5"></a>}</span></code></pre></div>
<p>The function takes the id of the visualisation the data is destined for, the data object itself, and a shiny session used to send the data. The id of the visualisation is sent as part of the message and will be used to retrieve the instance of the visualisation and subsequently apply the new dataset. Note that we give this message the <code>send-data</code> identifier, this will be needed when we write its handler.</p>
<p>There is one caveat that will make it such that the above will not work. To have gio.js work with data changes had to be made to the serialiser (using the <code>TOJSON_ARGS</code> attribute), this cannot be used here. The data being sent with Shiny via the session object the problem reoccurs: shiny, like htmlwidgets, serialises data frames column-wise and not row-wise. One can preview the way shiny serialises with <code>shiny:::toJSON</code> (three-colon).</p>
<div class="sourceCode" id="cb186"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb186-1"><a href="working-with-shiny.html#cb186-1"></a><span class="co"># preview shiny serialisation</span></span>
<span id="cb186-2"><a href="working-with-shiny.html#cb186-2"></a>shiny<span class="op">:::</span><span class="kw">toJSON</span>(arcs)</span></code></pre></div>
<pre><code>## {&quot;e&quot;:[&quot;CN&quot;,&quot;CN&quot;],&quot;i&quot;:[&quot;US&quot;,&quot;RU&quot;],&quot;v&quot;:[3300000,10000]}</code></pre>
<p>Unfortunately this serialiser cannot be changed, therefore we have to reformat the data to a list which resembles the JSON output desired, using <code>apply</code> to turn every row into a list will do the job in most cases.</p>
<div class="sourceCode" id="cb188"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb188-1"><a href="working-with-shiny.html#cb188-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb188-2"><a href="working-with-shiny.html#cb188-2"></a>gio_send_data &lt;-<span class="st"> </span><span class="cf">function</span>(id, data, <span class="dt">session =</span> shiny<span class="op">::</span><span class="kw">getDefaultReactiveDomain</span>()){</span>
<span id="cb188-3"><a href="working-with-shiny.html#cb188-3"></a>  message &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">id =</span> id, <span class="dt">data =</span> <span class="kw">apply</span>(data, <span class="dv">1</span>, as.list))</span>
<span id="cb188-4"><a href="working-with-shiny.html#cb188-4"></a>  session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&quot;send-data&quot;</span>, message)</span>
<span id="cb188-5"><a href="working-with-shiny.html#cb188-5"></a>}</span></code></pre></div>
</div>
<div id="retrieve-widget-instance" class="section level3" number="10.3.2">
<h3><span class="header-section-number">10.3.2</span> Retrieve Widget Instance</h3>
<p>We will need to be able to access the instance of the visualisation (<code>controller</code>) outside of the function <code>factory</code>. This can be made accessible by adding a function (technically a method) that returns the <code>controller</code>. Below we create a function called <code>getGlobe</code> which returns the <code>controller</code>.</p>
<div class="sourceCode" id="cb189"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb189-1"><a href="working-with-shiny.html#cb189-1"></a><span class="va">HTMLWidgets</span>.<span class="at">widget</span>(<span class="op">{</span></span>
<span id="cb189-2"><a href="working-with-shiny.html#cb189-2"></a></span>
<span id="cb189-3"><a href="working-with-shiny.html#cb189-3"></a>  <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;gio&#39;</span><span class="op">,</span></span>
<span id="cb189-4"><a href="working-with-shiny.html#cb189-4"></a></span>
<span id="cb189-5"><a href="working-with-shiny.html#cb189-5"></a>  <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;output&#39;</span><span class="op">,</span></span>
<span id="cb189-6"><a href="working-with-shiny.html#cb189-6"></a></span>
<span id="cb189-7"><a href="working-with-shiny.html#cb189-7"></a>  <span class="dt">factory</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> width<span class="op">,</span> height) <span class="op">{</span></span>
<span id="cb189-8"><a href="working-with-shiny.html#cb189-8"></a></span>
<span id="cb189-9"><a href="working-with-shiny.html#cb189-9"></a>    <span class="kw">var</span> controller<span class="op">;</span></span>
<span id="cb189-10"><a href="working-with-shiny.html#cb189-10"></a></span>
<span id="cb189-11"><a href="working-with-shiny.html#cb189-11"></a>    <span class="cf">return</span> <span class="op">{</span></span>
<span id="cb189-12"><a href="working-with-shiny.html#cb189-12"></a></span>
<span id="cb189-13"><a href="working-with-shiny.html#cb189-13"></a>      <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb189-14"><a href="working-with-shiny.html#cb189-14"></a></span>
<span id="cb189-15"><a href="working-with-shiny.html#cb189-15"></a>        <span class="va">el</span>.<span class="at">innerHTML</span> <span class="op">=</span> <span class="st">&#39;&#39;</span><span class="op">;</span></span>
<span id="cb189-16"><a href="working-with-shiny.html#cb189-16"></a>        controller <span class="op">=</span> <span class="kw">new</span> <span class="va">GIO</span>.<span class="at">Controller</span>(el)<span class="op">;</span></span>
<span id="cb189-17"><a href="working-with-shiny.html#cb189-17"></a>        </span>
<span id="cb189-18"><a href="working-with-shiny.html#cb189-18"></a>        <span class="co">// add data</span></span>
<span id="cb189-19"><a href="working-with-shiny.html#cb189-19"></a>        <span class="va">controller</span>.<span class="at">addData</span>(<span class="va">x</span>.<span class="at">data</span>)<span class="op">;</span></span>
<span id="cb189-20"><a href="working-with-shiny.html#cb189-20"></a></span>
<span id="cb189-21"><a href="working-with-shiny.html#cb189-21"></a>        <span class="va">controller</span>.<span class="at">setStyle</span>(<span class="va">x</span>.<span class="at">style</span>)<span class="op">;</span></span>
<span id="cb189-22"><a href="working-with-shiny.html#cb189-22"></a></span>
<span id="cb189-23"><a href="working-with-shiny.html#cb189-23"></a>        <span class="co">// callback</span></span>
<span id="cb189-24"><a href="working-with-shiny.html#cb189-24"></a>        <span class="va">controller</span>.<span class="at">onCountryPicked</span>(callback)<span class="op">;</span></span>
<span id="cb189-25"><a href="working-with-shiny.html#cb189-25"></a></span>
<span id="cb189-26"><a href="working-with-shiny.html#cb189-26"></a>        <span class="kw">function</span> <span class="at">callback</span> (selectedCountry<span class="op">,</span> relatedCountries) <span class="op">{</span></span>
<span id="cb189-27"><a href="working-with-shiny.html#cb189-27"></a>          <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="va">el</span>.<span class="at">id</span> <span class="op">+</span> <span class="st">&#39;_selected&#39;</span><span class="op">,</span> selectedCountry)<span class="op">;</span></span>
<span id="cb189-28"><a href="working-with-shiny.html#cb189-28"></a>          <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="va">el</span>.<span class="at">id</span> <span class="op">+</span> <span class="st">&#39;_related:gio.related.countries&#39;</span><span class="op">,</span> relatedCountries)<span class="op">;</span></span>
<span id="cb189-29"><a href="working-with-shiny.html#cb189-29"></a>        <span class="op">}</span></span>
<span id="cb189-30"><a href="working-with-shiny.html#cb189-30"></a></span>
<span id="cb189-31"><a href="working-with-shiny.html#cb189-31"></a>        <span class="co">// render</span></span>
<span id="cb189-32"><a href="working-with-shiny.html#cb189-32"></a>        <span class="va">controller</span>.<span class="at">init</span>()<span class="op">;</span></span>
<span id="cb189-33"><a href="working-with-shiny.html#cb189-33"></a></span>
<span id="cb189-34"><a href="working-with-shiny.html#cb189-34"></a>      <span class="op">},</span></span>
<span id="cb189-35"><a href="working-with-shiny.html#cb189-35"></a></span>
<span id="cb189-36"><a href="working-with-shiny.html#cb189-36"></a>      <span class="dt">resize</span><span class="op">:</span> <span class="kw">function</span>(width<span class="op">,</span> height) <span class="op">{</span></span>
<span id="cb189-37"><a href="working-with-shiny.html#cb189-37"></a></span>
<span id="cb189-38"><a href="working-with-shiny.html#cb189-38"></a>        <span class="va">controller</span>.<span class="at">resizeUpdate</span>()</span>
<span id="cb189-39"><a href="working-with-shiny.html#cb189-39"></a></span>
<span id="cb189-40"><a href="working-with-shiny.html#cb189-40"></a>      <span class="op">},</span></span>
<span id="cb189-41"><a href="working-with-shiny.html#cb189-41"></a></span>
<span id="cb189-42"><a href="working-with-shiny.html#cb189-42"></a>      <span class="co">// add getGlobe to retrieve controller</span></span>
<span id="cb189-43"><a href="working-with-shiny.html#cb189-43"></a>      <span class="dt">getGlobe</span><span class="op">:</span> <span class="kw">function</span>()<span class="op">{</span></span>
<span id="cb189-44"><a href="working-with-shiny.html#cb189-44"></a>        <span class="cf">return</span> controller<span class="op">;</span></span>
<span id="cb189-45"><a href="working-with-shiny.html#cb189-45"></a>      <span class="op">}</span></span>
<span id="cb189-46"><a href="working-with-shiny.html#cb189-46"></a></span>
<span id="cb189-47"><a href="working-with-shiny.html#cb189-47"></a>    <span class="op">};</span></span>
<span id="cb189-48"><a href="working-with-shiny.html#cb189-48"></a>  <span class="op">}</span></span>
<span id="cb189-49"><a href="working-with-shiny.html#cb189-49"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>Then, anywhere in the <code>gio.js</code> file, we create a function which uses <code>HTMLWidgets.find</code> to retrieve the instance of the htmlwidgets, it takes a selector as input. We concatenate the pound sign to select the widget based its id (<code>#id</code>, <code>.class</code>). This in effect returns an object which includes all the functions returned by the <code>factory</code> function: <code>renderValue</code>, <code>resize</code>, and <code>getGlobe</code>. We can therefore use the <code>getGlobe</code> method available from that object to retrieve the actual <code>controller</code>.</p>
<div class="sourceCode" id="cb190"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb190-1"><a href="working-with-shiny.html#cb190-1"></a><span class="co">// gio.js</span></span>
<span id="cb190-2"><a href="working-with-shiny.html#cb190-2"></a><span class="kw">function</span> <span class="at">get_gio</span>(id)<span class="op">{</span></span>
<span id="cb190-3"><a href="working-with-shiny.html#cb190-3"></a>  <span class="kw">var</span> widget <span class="op">=</span> <span class="va">HTMLWidgets</span>.<span class="at">find</span>(<span class="st">&quot;#&quot;</span> <span class="op">+</span> id)<span class="op">;</span></span>
<span id="cb190-4"><a href="working-with-shiny.html#cb190-4"></a>  <span class="kw">var</span> globe <span class="op">=</span> <span class="va">widget</span>.<span class="at">getGlobe</span>()<span class="op">;</span></span>
<span id="cb190-5"><a href="working-with-shiny.html#cb190-5"></a>  <span class="cf">return</span> globe<span class="op">;</span></span>
<span id="cb190-6"><a href="working-with-shiny.html#cb190-6"></a><span class="op">}</span></span></code></pre></div>
</div>
<div id="handle-data" class="section level3" number="10.3.3">
<h3><span class="header-section-number">10.3.3</span> Handle Data</h3>
<p>We can now turn the attention to actually applying the data sent from the R server to the visualisation: the “message handler.” Registering the message handler is only relevant if shiny is running, therefore HTMLWidgets comes with a function to check whether that is the case which is useful to avoid needless errors. We can thus use it in an if statement in which all message handlers will be registered.</p>
<div class="sourceCode" id="cb191"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb191-1"><a href="working-with-shiny.html#cb191-1"></a><span class="co">// gio.js</span></span>
<span id="cb191-2"><a href="working-with-shiny.html#cb191-2"></a></span>
<span id="cb191-3"><a href="working-with-shiny.html#cb191-3"></a><span class="co">// check if shiny running</span></span>
<span id="cb191-4"><a href="working-with-shiny.html#cb191-4"></a><span class="cf">if</span> (<span class="va">HTMLWidgets</span>.<span class="at">shinyMode</span>)<span class="op">{</span></span>
<span id="cb191-5"><a href="working-with-shiny.html#cb191-5"></a></span>
<span id="cb191-6"><a href="working-with-shiny.html#cb191-6"></a>  <span class="co">// send-data message handler</span></span>
<span id="cb191-7"><a href="working-with-shiny.html#cb191-7"></a>  <span class="va">Shiny</span>.<span class="at">addCustomMessageHandler</span>(type <span class="op">=</span> <span class="st">&#39;send-data&#39;</span><span class="op">,</span> <span class="kw">function</span>(message) <span class="op">{</span></span>
<span id="cb191-8"><a href="working-with-shiny.html#cb191-8"></a></span>
<span id="cb191-9"><a href="working-with-shiny.html#cb191-9"></a>  <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb191-10"><a href="working-with-shiny.html#cb191-10"></a></span>
<span id="cb191-11"><a href="working-with-shiny.html#cb191-11"></a><span class="op">}</span></span></code></pre></div>
<p>What the currently empty <code>send-alert</code> message handler should do is fetch the widget using the <code>id</code> sent from R with the <code>get_gio</code> function and then use the <code>addData</code> method to override the previously define arcs.</p>
<div class="sourceCode" id="cb192"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb192-1"><a href="working-with-shiny.html#cb192-1"></a><span class="co">// gio.js</span></span>
<span id="cb192-2"><a href="working-with-shiny.html#cb192-2"></a></span>
<span id="cb192-3"><a href="working-with-shiny.html#cb192-3"></a><span class="co">// check if shiny running</span></span>
<span id="cb192-4"><a href="working-with-shiny.html#cb192-4"></a><span class="cf">if</span> (<span class="va">HTMLWidgets</span>.<span class="at">shinyMode</span>)<span class="op">{</span></span>
<span id="cb192-5"><a href="working-with-shiny.html#cb192-5"></a></span>
<span id="cb192-6"><a href="working-with-shiny.html#cb192-6"></a>  <span class="co">// send-data message handler</span></span>
<span id="cb192-7"><a href="working-with-shiny.html#cb192-7"></a>  <span class="va">Shiny</span>.<span class="at">addCustomMessageHandler</span>(type <span class="op">=</span> <span class="st">&#39;send-data&#39;</span><span class="op">,</span> <span class="kw">function</span>(message) <span class="op">{</span></span>
<span id="cb192-8"><a href="working-with-shiny.html#cb192-8"></a></span>
<span id="cb192-9"><a href="working-with-shiny.html#cb192-9"></a>    <span class="co">// retrieve controller</span></span>
<span id="cb192-10"><a href="working-with-shiny.html#cb192-10"></a>    <span class="kw">var</span> controller <span class="op">=</span> <span class="at">get_gio</span>(<span class="va">message</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb192-11"><a href="working-with-shiny.html#cb192-11"></a></span>
<span id="cb192-12"><a href="working-with-shiny.html#cb192-12"></a>    <span class="co">// add data</span></span>
<span id="cb192-13"><a href="working-with-shiny.html#cb192-13"></a>    <span class="va">controller</span>.<span class="at">addData</span>(<span class="va">message</span>.<span class="at">data</span>)<span class="op">;</span></span>
<span id="cb192-14"><a href="working-with-shiny.html#cb192-14"></a></span>
<span id="cb192-15"><a href="working-with-shiny.html#cb192-15"></a>  <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb192-16"><a href="working-with-shiny.html#cb192-16"></a></span>
<span id="cb192-17"><a href="working-with-shiny.html#cb192-17"></a><span class="op">}</span></span></code></pre></div>
<p>We can then build a shiny application to test the new functionality.</p>
<div class="sourceCode" id="cb193"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb193-1"><a href="working-with-shiny.html#cb193-1"></a><span class="kw">library</span>(gio)</span>
<span id="cb193-2"><a href="working-with-shiny.html#cb193-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb193-3"><a href="working-with-shiny.html#cb193-3"></a></span>
<span id="cb193-4"><a href="working-with-shiny.html#cb193-4"></a><span class="co"># two phoney datasets</span></span>
<span id="cb193-5"><a href="working-with-shiny.html#cb193-5"></a>arcs1 &lt;-<span class="st"> </span><span class="kw">data.frame</span>(</span>
<span id="cb193-6"><a href="working-with-shiny.html#cb193-6"></a>  <span class="dt">e =</span> <span class="kw">c</span>(<span class="st">&quot;US&quot;</span>, <span class="st">&quot;CN&quot;</span>, <span class="st">&quot;RU&quot;</span>),</span>
<span id="cb193-7"><a href="working-with-shiny.html#cb193-7"></a>  <span class="dt">i =</span> <span class="kw">c</span>(<span class="st">&quot;CN&quot;</span>, <span class="st">&quot;RU&quot;</span>, <span class="st">&quot;US&quot;</span>),</span>
<span id="cb193-8"><a href="working-with-shiny.html#cb193-8"></a>  <span class="dt">v =</span> <span class="kw">c</span>(<span class="dv">100</span>, <span class="dv">120</span>, <span class="dv">130</span>)</span>
<span id="cb193-9"><a href="working-with-shiny.html#cb193-9"></a>)</span>
<span id="cb193-10"><a href="working-with-shiny.html#cb193-10"></a></span>
<span id="cb193-11"><a href="working-with-shiny.html#cb193-11"></a>arcs2 &lt;-<span class="st"> </span><span class="kw">data.frame</span>(</span>
<span id="cb193-12"><a href="working-with-shiny.html#cb193-12"></a>  <span class="dt">e =</span> <span class="kw">c</span>(<span class="st">&quot;CN&quot;</span>, <span class="st">&quot;CN&quot;</span>, <span class="st">&quot;JP&quot;</span>),</span>
<span id="cb193-13"><a href="working-with-shiny.html#cb193-13"></a>  <span class="dt">i =</span> <span class="kw">c</span>(<span class="st">&quot;IN&quot;</span>, <span class="st">&quot;JP&quot;</span>, <span class="st">&quot;US&quot;</span>),</span>
<span id="cb193-14"><a href="working-with-shiny.html#cb193-14"></a>  <span class="dt">v =</span> <span class="kw">c</span>(<span class="dv">100</span>, <span class="dv">120</span>, <span class="dv">130</span>)</span>
<span id="cb193-15"><a href="working-with-shiny.html#cb193-15"></a>)</span>
<span id="cb193-16"><a href="working-with-shiny.html#cb193-16"></a></span>
<span id="cb193-17"><a href="working-with-shiny.html#cb193-17"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb193-18"><a href="working-with-shiny.html#cb193-18"></a>  <span class="kw">selectInput</span>(</span>
<span id="cb193-19"><a href="working-with-shiny.html#cb193-19"></a>    <span class="st">&quot;dataset&quot;</span>, </span>
<span id="cb193-20"><a href="working-with-shiny.html#cb193-20"></a>    <span class="st">&quot;Select a dataset&quot;</span>, </span>
<span id="cb193-21"><a href="working-with-shiny.html#cb193-21"></a>    <span class="dt">choices =</span> <span class="kw">c</span>(<span class="st">&quot;First&quot;</span>, <span class="st">&quot;Second&quot;</span>)</span>
<span id="cb193-22"><a href="working-with-shiny.html#cb193-22"></a>  ),</span>
<span id="cb193-23"><a href="working-with-shiny.html#cb193-23"></a>  <span class="kw">gioOutput</span>(<span class="st">&quot;globe&quot;</span>)</span>
<span id="cb193-24"><a href="working-with-shiny.html#cb193-24"></a>)</span>
<span id="cb193-25"><a href="working-with-shiny.html#cb193-25"></a></span>
<span id="cb193-26"><a href="working-with-shiny.html#cb193-26"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb193-27"><a href="working-with-shiny.html#cb193-27"></a></span>
<span id="cb193-28"><a href="working-with-shiny.html#cb193-28"></a>  reactive_arcs &lt;-<span class="st"> </span><span class="kw">reactive</span>({</span>
<span id="cb193-29"><a href="working-with-shiny.html#cb193-29"></a>    <span class="cf">if</span>(input<span class="op">$</span>dataset <span class="op">==</span><span class="st"> &quot;First&quot;</span>) </span>
<span id="cb193-30"><a href="working-with-shiny.html#cb193-30"></a>      <span class="kw">return</span>(arcs1)</span>
<span id="cb193-31"><a href="working-with-shiny.html#cb193-31"></a>    <span class="kw">return</span>(arcs2)</span>
<span id="cb193-32"><a href="working-with-shiny.html#cb193-32"></a>  })</span>
<span id="cb193-33"><a href="working-with-shiny.html#cb193-33"></a></span>
<span id="cb193-34"><a href="working-with-shiny.html#cb193-34"></a>  output<span class="op">$</span>globe &lt;-<span class="st"> </span><span class="kw">renderGio</span>({</span>
<span id="cb193-35"><a href="working-with-shiny.html#cb193-35"></a>    <span class="kw">gio</span>(arcs1)</span>
<span id="cb193-36"><a href="working-with-shiny.html#cb193-36"></a>  })</span>
<span id="cb193-37"><a href="working-with-shiny.html#cb193-37"></a></span>
<span id="cb193-38"><a href="working-with-shiny.html#cb193-38"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>dataset, {</span>
<span id="cb193-39"><a href="working-with-shiny.html#cb193-39"></a>    <span class="cf">if</span>(input<span class="op">$</span>dataset <span class="op">==</span><span class="st"> &quot;First&quot;</span>)</span>
<span id="cb193-40"><a href="working-with-shiny.html#cb193-40"></a>      data &lt;-<span class="st"> </span>arcs1</span>
<span id="cb193-41"><a href="working-with-shiny.html#cb193-41"></a>    <span class="cf">else</span></span>
<span id="cb193-42"><a href="working-with-shiny.html#cb193-42"></a>      data &lt;-<span class="st"> </span>arcs2</span>
<span id="cb193-43"><a href="working-with-shiny.html#cb193-43"></a>    </span>
<span id="cb193-44"><a href="working-with-shiny.html#cb193-44"></a>    <span class="kw">gio_send_data</span>(<span class="st">&quot;globe&quot;</span>, data)</span>
<span id="cb193-45"><a href="working-with-shiny.html#cb193-45"></a>  })</span>
<span id="cb193-46"><a href="working-with-shiny.html#cb193-46"></a></span>
<span id="cb193-47"><a href="working-with-shiny.html#cb193-47"></a>}</span>
<span id="cb193-48"><a href="working-with-shiny.html#cb193-48"></a></span>
<span id="cb193-49"><a href="working-with-shiny.html#cb193-49"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<p>Switching dataset with the dropdown only changes the data, it makes for a much smoother animation, even the difference in the speed at which the effect is visible on the visualisation is perceivable.</p>
</div>
</div>
<div id="proxy-function" class="section level2" number="10.4">
<h2><span class="header-section-number">10.4</span> Proxy Function</h2>
<p>Before we add other similar functions we ought to pause and consider the API this provides the user. There are two points, every function such as <code>gio_send_data</code>, will need to accept the <code>id</code> and <code>session</code> arguments. It will be tedious to so every time, following the old “don’t repeat yourself” adage we ought to abstract this further.</p>
<p>This can be remedied to by introducing what is often referred to as a “proxy.” A proxy is just a representation of the graph, or pragmatically, an object that contains the id of the visualisation and a shiny session. This object can subsequently be piped to other functions thereby providing not only a cleaner but also a more consistent API.</p>
<div class="sourceCode" id="cb194"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb194-1"><a href="working-with-shiny.html#cb194-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb194-2"><a href="working-with-shiny.html#cb194-2"></a>gio_proxy &lt;-<span class="st"> </span><span class="cf">function</span>(id, <span class="dt">session =</span> shiny<span class="op">::</span><span class="kw">getDefaultReactiveDomain</span>()){</span>
<span id="cb194-3"><a href="working-with-shiny.html#cb194-3"></a>  <span class="kw">list</span>(<span class="dt">id =</span> id, <span class="dt">session =</span> session)</span>
<span id="cb194-4"><a href="working-with-shiny.html#cb194-4"></a>}</span></code></pre></div>
<p>Above we create a function called <code>gio_proxy</code> which takes the <code>id</code> of the chart one wants to build a proxy off, as well as the shiny <code>session</code>, they are returned in the form of a list. Next, we should adapt the <code>gio_send_data</code> so that it accepts the output of <code>gioProxy</code> instead of the <code>id</code> and <code>session</code> as done previously. In order to allow chaining such functions we also make sure it returns the <code>proxy</code> object.</p>
<div class="sourceCode" id="cb195"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb195-1"><a href="working-with-shiny.html#cb195-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb195-2"><a href="working-with-shiny.html#cb195-2"></a>gio_send_data &lt;-<span class="st"> </span><span class="cf">function</span>(proxy, data){</span>
<span id="cb195-3"><a href="working-with-shiny.html#cb195-3"></a>  message &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">id =</span> proxy<span class="op">$</span>id, <span class="dt">data =</span> <span class="kw">apply</span>(data, <span class="dv">1</span>, as.list))</span>
<span id="cb195-4"><a href="working-with-shiny.html#cb195-4"></a>  proxy<span class="op">$</span>session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&quot;send-data&quot;</span>, message)</span>
<span id="cb195-5"><a href="working-with-shiny.html#cb195-5"></a>  <span class="kw">return</span>(proxy)</span>
<span id="cb195-6"><a href="working-with-shiny.html#cb195-6"></a>}</span></code></pre></div>
</div>
<div id="clear-data" class="section level2" number="10.5">
<h2><span class="header-section-number">10.5</span> Clear Data</h2>
<p>In order to actively demonstrate the advantage of the “proxy” function as well as to hammer home how such functions work, we shall build another which removes all data from the globe. In JavaScript it’s as simple as <code>controller.clearData();</code>.</p>
<p>The journey starts with the R code where we create a new function that sends a message to clear the data, the message only needs to contain the id of the visualisation from which data needs to be cleared, as before it will be used to retrieve the <code>controller</code> from which the <code>clearData</code> method is available.</p>
<div class="sourceCode" id="cb196"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb196-1"><a href="working-with-shiny.html#cb196-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb196-2"><a href="working-with-shiny.html#cb196-2"></a>gio_clear_data &lt;-<span class="st"> </span><span class="cf">function</span>(proxy){</span>
<span id="cb196-3"><a href="working-with-shiny.html#cb196-3"></a>  message &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">id =</span> proxy<span class="op">$</span>id)</span>
<span id="cb196-4"><a href="working-with-shiny.html#cb196-4"></a>  proxy<span class="op">$</span>session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&quot;clear-data&quot;</span>, message)</span>
<span id="cb196-5"><a href="working-with-shiny.html#cb196-5"></a>  <span class="kw">return</span>(proxy)</span>
<span id="cb196-6"><a href="working-with-shiny.html#cb196-6"></a>}</span></code></pre></div>
<p>Now onto the JavaScript code to catch that message and actually clear the data from the globe. That function is very similar to what was previously shown, the only difference is the name of the message handler and the method used on the controller.</p>
<div class="sourceCode" id="cb197"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb197-1"><a href="working-with-shiny.html#cb197-1"></a><span class="co">// gio.js</span></span>
<span id="cb197-2"><a href="working-with-shiny.html#cb197-2"></a><span class="va">Shiny</span>.<span class="at">addCustomMessageHandler</span>(type <span class="op">=</span> <span class="st">&#39;clear-data&#39;</span><span class="op">,</span> <span class="kw">function</span>(message) <span class="op">{</span></span>
<span id="cb197-3"><a href="working-with-shiny.html#cb197-3"></a>  <span class="kw">var</span> controller <span class="op">=</span> <span class="at">get_gio</span>(<span class="va">message</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb197-4"><a href="working-with-shiny.html#cb197-4"></a>  <span class="va">controller</span>.<span class="at">clearData</span>()<span class="op">;</span></span>
<span id="cb197-5"><a href="working-with-shiny.html#cb197-5"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>Then one can build an application to test that new function. We build a shiny application with a button to add the data to the visualisation and another to clear data from it.</p>
<div class="sourceCode" id="cb198"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb198-1"><a href="working-with-shiny.html#cb198-1"></a><span class="kw">library</span>(gio)</span>
<span id="cb198-2"><a href="working-with-shiny.html#cb198-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb198-3"><a href="working-with-shiny.html#cb198-3"></a></span>
<span id="cb198-4"><a href="working-with-shiny.html#cb198-4"></a><span class="co"># phoney dataset</span></span>
<span id="cb198-5"><a href="working-with-shiny.html#cb198-5"></a>arcs &lt;-<span class="st"> </span><span class="kw">data.frame</span>(</span>
<span id="cb198-6"><a href="working-with-shiny.html#cb198-6"></a>  <span class="dt">e =</span> <span class="kw">c</span>(<span class="st">&quot;US&quot;</span>, <span class="st">&quot;CN&quot;</span>, <span class="st">&quot;RU&quot;</span>),</span>
<span id="cb198-7"><a href="working-with-shiny.html#cb198-7"></a>  <span class="dt">i =</span> <span class="kw">c</span>(<span class="st">&quot;CN&quot;</span>, <span class="st">&quot;RU&quot;</span>, <span class="st">&quot;US&quot;</span>),</span>
<span id="cb198-8"><a href="working-with-shiny.html#cb198-8"></a>  <span class="dt">v =</span> <span class="kw">c</span>(<span class="dv">100</span>, <span class="dv">120</span>, <span class="dv">130</span>)</span>
<span id="cb198-9"><a href="working-with-shiny.html#cb198-9"></a>)</span>
<span id="cb198-10"><a href="working-with-shiny.html#cb198-10"></a></span>
<span id="cb198-11"><a href="working-with-shiny.html#cb198-11"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb198-12"><a href="working-with-shiny.html#cb198-12"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;load&quot;</span>, <span class="st">&quot;Load data&quot;</span>),</span>
<span id="cb198-13"><a href="working-with-shiny.html#cb198-13"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;clear&quot;</span>, <span class="st">&quot;Clear data&quot;</span>),</span>
<span id="cb198-14"><a href="working-with-shiny.html#cb198-14"></a>  <span class="kw">gioOutput</span>(<span class="st">&quot;globe&quot;</span>)</span>
<span id="cb198-15"><a href="working-with-shiny.html#cb198-15"></a>)</span>
<span id="cb198-16"><a href="working-with-shiny.html#cb198-16"></a></span>
<span id="cb198-17"><a href="working-with-shiny.html#cb198-17"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb198-18"><a href="working-with-shiny.html#cb198-18"></a></span>
<span id="cb198-19"><a href="working-with-shiny.html#cb198-19"></a>  output<span class="op">$</span>globe &lt;-<span class="st"> </span><span class="kw">renderGio</span>({</span>
<span id="cb198-20"><a href="working-with-shiny.html#cb198-20"></a>    <span class="kw">gio</span>(arcs)</span>
<span id="cb198-21"><a href="working-with-shiny.html#cb198-21"></a>  })</span>
<span id="cb198-22"><a href="working-with-shiny.html#cb198-22"></a></span>
<span id="cb198-23"><a href="working-with-shiny.html#cb198-23"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>load, {</span>
<span id="cb198-24"><a href="working-with-shiny.html#cb198-24"></a>    <span class="kw">gio_proxy</span>(<span class="st">&quot;globe&quot;</span>) <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb198-25"><a href="working-with-shiny.html#cb198-25"></a><span class="st">      </span><span class="kw">gio_send_data</span>(arcs)</span>
<span id="cb198-26"><a href="working-with-shiny.html#cb198-26"></a>  })</span>
<span id="cb198-27"><a href="working-with-shiny.html#cb198-27"></a></span>
<span id="cb198-28"><a href="working-with-shiny.html#cb198-28"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>clear, {</span>
<span id="cb198-29"><a href="working-with-shiny.html#cb198-29"></a>    <span class="kw">gio_proxy</span>(<span class="st">&quot;globe&quot;</span>) <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb198-30"><a href="working-with-shiny.html#cb198-30"></a><span class="st">      </span><span class="kw">gio_clear_data</span>()</span>
<span id="cb198-31"><a href="working-with-shiny.html#cb198-31"></a>  })</span>
<span id="cb198-32"><a href="working-with-shiny.html#cb198-32"></a></span>
<span id="cb198-33"><a href="working-with-shiny.html#cb198-33"></a>}</span>
<span id="cb198-34"><a href="working-with-shiny.html#cb198-34"></a></span>
<span id="cb198-35"><a href="working-with-shiny.html#cb198-35"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/gio-shiny-clear.png" alt="" />
<p class="caption">Gio with clear data proxy</p>
</div>
</div>
<div id="update" class="section level2" number="10.6">
<h2><span class="header-section-number">10.6</span> Update</h2>
<p>The previous proxies defined worked for reasons unbeknownst to the author of this book. It will not work with all methods. The reason it will not work is one that is likely to occur with many other visualisation libraries. For instance, one can attempt to develop a function to dynamically change the style without having to redraw the entire globe, starting again with the R function.</p>
<div class="sourceCode" id="cb199"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb199-1"><a href="working-with-shiny.html#cb199-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb199-2"><a href="working-with-shiny.html#cb199-2"></a>gio_set_style &lt;-<span class="st"> </span><span class="cf">function</span>(proxy, style){</span>
<span id="cb199-3"><a href="working-with-shiny.html#cb199-3"></a>  message &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">id =</span> proxy<span class="op">$</span>id, <span class="dt">style =</span> style)</span>
<span id="cb199-4"><a href="working-with-shiny.html#cb199-4"></a>  proxy<span class="op">$</span>session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&quot;set-style&quot;</span>, message)</span>
<span id="cb199-5"><a href="working-with-shiny.html#cb199-5"></a>  <span class="kw">return</span>(proxy)</span>
<span id="cb199-6"><a href="working-with-shiny.html#cb199-6"></a>}</span></code></pre></div>
<p>Then adding the JavaScript handler.</p>
<div class="sourceCode" id="cb200"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb200-1"><a href="working-with-shiny.html#cb200-1"></a><span class="va">Shiny</span>.<span class="at">addCustomMessageHandler</span>(type <span class="op">=</span> <span class="st">&#39;set-style&#39;</span><span class="op">,</span> <span class="kw">function</span>(message) <span class="op">{</span></span>
<span id="cb200-2"><a href="working-with-shiny.html#cb200-2"></a>  <span class="kw">var</span> controller <span class="op">=</span> <span class="at">get_gio</span>(<span class="va">message</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb200-3"><a href="working-with-shiny.html#cb200-3"></a>  <span class="va">controller</span>.<span class="at">setStyle</span>(<span class="va">message</span>.<span class="at">style</span>)<span class="op">;</span></span>
<span id="cb200-4"><a href="working-with-shiny.html#cb200-4"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>At this stage one can try the function in a shiny application but it will not work because most such methods that change underlying aspects of a visualisation will not be reflected in real time. Gio.js, and many other libraries, will require one to explicitly ask for an update so the changes take effect. This has multiple advantages, one can stack multiple visual changes to execute them at the same time, and one can manage the load on the front-end.</p>
<div class="sourceCode" id="cb201"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb201-1"><a href="working-with-shiny.html#cb201-1"></a><span class="va">Shiny</span>.<span class="at">addCustomMessageHandler</span>(type <span class="op">=</span> <span class="st">&#39;set-style&#39;</span><span class="op">,</span> <span class="kw">function</span>(message) <span class="op">{</span></span>
<span id="cb201-2"><a href="working-with-shiny.html#cb201-2"></a>  <span class="kw">var</span> controller <span class="op">=</span> <span class="at">get_gio</span>(<span class="va">message</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb201-3"><a href="working-with-shiny.html#cb201-3"></a>  <span class="va">controller</span>.<span class="at">setStyle</span>(<span class="va">message</span>.<span class="at">style</span>)<span class="op">;</span></span>
<span id="cb201-4"><a href="working-with-shiny.html#cb201-4"></a>  <span class="va">controller</span>.<span class="at">update</span>()<span class="op">;</span> <span class="co">// force update the visualisation</span></span>
<span id="cb201-5"><a href="working-with-shiny.html#cb201-5"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>This forces the chart to update, applying the new style. Below we write an application that provides a dropdown to switch between two styles.</p>
<div class="sourceCode" id="cb202"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb202-1"><a href="working-with-shiny.html#cb202-1"></a><span class="kw">library</span>(gio)</span>
<span id="cb202-2"><a href="working-with-shiny.html#cb202-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb202-3"><a href="working-with-shiny.html#cb202-3"></a></span>
<span id="cb202-4"><a href="working-with-shiny.html#cb202-4"></a><span class="co"># two phoney datasets</span></span>
<span id="cb202-5"><a href="working-with-shiny.html#cb202-5"></a>arcs &lt;-<span class="st"> </span><span class="kw">data.frame</span>(</span>
<span id="cb202-6"><a href="working-with-shiny.html#cb202-6"></a>  <span class="dt">e =</span> <span class="kw">c</span>(<span class="st">&quot;US&quot;</span>, <span class="st">&quot;CN&quot;</span>, <span class="st">&quot;RU&quot;</span>),</span>
<span id="cb202-7"><a href="working-with-shiny.html#cb202-7"></a>  <span class="dt">i =</span> <span class="kw">c</span>(<span class="st">&quot;CN&quot;</span>, <span class="st">&quot;RU&quot;</span>, <span class="st">&quot;US&quot;</span>),</span>
<span id="cb202-8"><a href="working-with-shiny.html#cb202-8"></a>  <span class="dt">v =</span> <span class="kw">c</span>(<span class="dv">100</span>, <span class="dv">120</span>, <span class="dv">130</span>)</span>
<span id="cb202-9"><a href="working-with-shiny.html#cb202-9"></a>)</span>
<span id="cb202-10"><a href="working-with-shiny.html#cb202-10"></a></span>
<span id="cb202-11"><a href="working-with-shiny.html#cb202-11"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb202-12"><a href="working-with-shiny.html#cb202-12"></a>  <span class="kw">selectInput</span>(</span>
<span id="cb202-13"><a href="working-with-shiny.html#cb202-13"></a>    <span class="st">&quot;style&quot;</span>, </span>
<span id="cb202-14"><a href="working-with-shiny.html#cb202-14"></a>    <span class="st">&quot;Select a style&quot;</span>, </span>
<span id="cb202-15"><a href="working-with-shiny.html#cb202-15"></a>    <span class="dt">choices =</span> <span class="kw">c</span>(<span class="st">&quot;blueInk&quot;</span>, <span class="st">&quot;earlySpring&quot;</span>)</span>
<span id="cb202-16"><a href="working-with-shiny.html#cb202-16"></a>  ),</span>
<span id="cb202-17"><a href="working-with-shiny.html#cb202-17"></a>  <span class="kw">gioOutput</span>(<span class="st">&quot;globe&quot;</span>)</span>
<span id="cb202-18"><a href="working-with-shiny.html#cb202-18"></a>)</span>
<span id="cb202-19"><a href="working-with-shiny.html#cb202-19"></a></span>
<span id="cb202-20"><a href="working-with-shiny.html#cb202-20"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb202-21"><a href="working-with-shiny.html#cb202-21"></a>  output<span class="op">$</span>globe &lt;-<span class="st"> </span><span class="kw">renderGio</span>({</span>
<span id="cb202-22"><a href="working-with-shiny.html#cb202-22"></a>    <span class="kw">gio</span>(arcs1)</span>
<span id="cb202-23"><a href="working-with-shiny.html#cb202-23"></a>  })</span>
<span id="cb202-24"><a href="working-with-shiny.html#cb202-24"></a></span>
<span id="cb202-25"><a href="working-with-shiny.html#cb202-25"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>style, {</span>
<span id="cb202-26"><a href="working-with-shiny.html#cb202-26"></a>    <span class="kw">gio_proxy</span>(<span class="st">&quot;globe&quot;</span>) <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb202-27"><a href="working-with-shiny.html#cb202-27"></a><span class="st">      </span><span class="kw">gio_set_style</span>(input<span class="op">$</span>style)</span>
<span id="cb202-28"><a href="working-with-shiny.html#cb202-28"></a>  })</span>
<span id="cb202-29"><a href="working-with-shiny.html#cb202-29"></a></span>
<span id="cb202-30"><a href="working-with-shiny.html#cb202-30"></a>}</span>
<span id="cb202-31"><a href="working-with-shiny.html#cb202-31"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/gio-shiny-style.png" alt="" />
<p class="caption">Gio with dynamic style</p>
</div>

</div>
</div>



            </section>

          </div>
        </div>
      </div>
<a href="crosstalk.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="discover.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/3-27-htmlwidgets-shiny.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
